export function format(fmt = "YYYY-MM-DD HH:mm:ss") {
  const weeks = ["日", "一", "二", "三", "四", "五", "六"];
  const weekengs = [
    "Sunday",
    "Monday",
    "Tuesday",
    "Wednesday",
    "Thursday",
    "Friday",
    "Saturday",
  ];
  var o = {
    "Y+": this.getFullYear(),
    "M+": this.getMonth() + 1,
    "D+": this.getDate(),
    "H+": this.getHours(),
    "h+": this.getHours(),
    "m+": this.getMinutes(),
    "s+": this.getSeconds(),
    W: weeks[this.getDay()],
    w: weekengs[this.getDay()],
    www: weekengs[this.getDay()]?.substring(0, 3),
    S: this.getMilliseconds(),
  };
  for (var k in o)
    if (new RegExp("(" + k + ")").test(fmt))
      fmt = fmt.replace(
        RegExp.$1,
        RegExp.$1.length == 1
          ? o[k]
          : ("00" + o[k]).substr(("00" + o[k]).length - RegExp.$1.length)
      );
  return fmt;
}

function YYYYmd(ymd) {
  return [ymd[0], ymd[1] - 1, ymd[2]];
}

export function startOf(type) {
  let year, month, d, h, m, s, ms;
  year = this.getFullYear();
  month = this.getMonth();
  d = this.getDate();
  h = this.getHours();
  m = this.getMinutes();
  s = this.getSeconds();
  ms = this.getMilliseconds();
  switch (type) {
    case "year":
    case "y":
      month = 0;
    case "month":
    case "M":
      d = 1;
    case "day":
    case "d":
      h = 0;
    case "hour":
    case "h":
      m = 0;
    case "minute":
    case "m":
      s = 0;
    case "second":
    case "s":
      ms = 0;
      break;
  }
  return new Date(year, month, d, h, m, s, ms);
}

export function add(count, type = "d") {
  let year, month, d, h, m, s, ms;
  year = this.getFullYear();
  month = this.getMonth();
  d = this.getDate();
  h = this.getHours();
  m = this.getMinutes();
  s = this.getSeconds();
  ms = this.getMilliseconds();
  switch (type) {
    case "year":
    case "y":
      year += count;
      break;
    case "month":
    case "M":
      month += count;
      break;
    case "week":
    case "w":
      d += count * 7;
      break;
    case "day":
    case "d":
      d += count;
      break;
    case "hour":
    case "h":
      h += count;
      break;
    case "minute":
    case "m":
      m += count;
      break;
    case "second":
    case "s":
      s += count;
      break;
    case "millisecond":
    case "ms":
      ms += count;
      break;
  }
  return new Date(year, month, d, h, m, s, ms);
}

export function diff(dt, type) {
  let times = Date.now();
  if (dt instanceof Date) times = dt.getTime();
  if (typeof dt === "string") times = Date.parse(dt);
  let diff = this.getTime() - times;
  switch (type) {
    case "day":
    case "d":
      return Math.round(diff / 100 / 60 / 60 / 24) / 10;
    case "hour":
    case "h":
      return Math.round(diff / 100 / 60 / 60) / 10;
    case "minute":
    case "m":
      return Math.round(diff / 100 / 60) / 10;
    case "second":
    case "s":
      return Math.round(diff / 100) / 10;
    default:
      return diff;
  }
}

export function daysInMonth() {
  return new Date(this.getFullYear(), this.getMonth() + 1, 0).getDate();
}

export function _valueOf(time) {
  if (time) {
    if (time instanceof Date) {
      return time;
    } else if (typeof time == "number") {
      return time;
    } else if (typeof time == "string") {
      const [dt, ti] = time.split(" ");
      return new Date(...YYYYmd(dt.split("-")), ...(ti ?? "0:0:0").split(":"));
    }
  }
  return new Date();
}
